home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
dnet2_10_13.lha
/
DNet
/
Amiga
/
Sourcen.lha
/
server
/
sterm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-14
|
7KB
|
311 lines
/*
* S_TERM.C
*
* DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
*
* Terminal window server.
* -Echo what is received in the window.
* -Transmit stuff typed on keyboard, echoing locally.
*
* Use FTERM on the other Amiga to connect.
*
* NOTE!!!! Spawned tasks are ... TASKS, not processes. No DOS calls
* allowed.
*/
#include "defs.h"
int NHandlers;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
PORT *HdPort;
PORT *LisPort;
short HandShakeSig;
int spawn_handler ARGS((void));
void __saveds term_task ARGS((void));
void HandleIoctl ARGS((short, short, char, WIN *, IOCON *, short*));
void setsize ARGS((IOCON *, void *, WIN *));
int
brk()
{
return(0);
}
void
#ifdef LATTICE
_main(str)
#else
_main(len,str)
#endif
char *str;
{
MSG *msg;
long mask, pmask, hdmask;
PROC *proc = (PROC *)FindTask(NULL);
onbreak(brk);
if (strncmp(str, "__dnet", 6) != 0) {
Version("STerm", VERSION, STERM_VERSION);
_exit(0);
}
LisPort= DListen(PORT_IALPHATERM);
WaitPort(&proc->pr_MsgPort);
ReplyMsg(GetMsg(&proc->pr_MsgPort));
if (!LisPort)
exit(1);
HdPort = CreatePort(NULL, 0);
HandShakeSig = AllocSignal(-1);
pmask = 1 << LisPort->mp_SigBit;
hdmask= 1 << HdPort->mp_SigBit;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
while (mask = Wait(SIGBREAKF_CTRL_C|pmask|hdmask)) {
if (mask & SIGBREAKF_CTRL_C)
break;
if (mask & hdmask) {
while (msg = GetMsg(HdPort)) {
--NHandlers;
FreeMem(msg, sizeof(*msg));
}
}
if (mask & pmask) {
while (spawn_handler())
;
}
}
DUnListen(LisPort);
while (NHandlers) {
WaitPort(HdPort);
msg = GetMsg(HdPort);
FreeMem(msg, sizeof(*msg));
--NHandlers;
}
DeletePort(HdPort);
CloseLibrary((LIB *)IntuitionBase);
CloseLibrary((LIB *)GfxBase);
}
/*
* Spawn a handler to accept the new connection, if any. Task sends
* a message to HdPort when through.
*/
int
spawn_handler()
{
long oldhan = NHandlers;
CreateTask("Term.channel", 0, (APTR)term_task, 2048);
Wait(1 << HandShakeSig);
return (oldhan != NHandlers);
}
static NW Nw = {
64, 64, 400, 100, -1, -1,
CLOSEWINDOW|NEWSIZE,
WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|ACTIVATE|NOCAREREFRESH,
NULL, NULL, (unsigned char *)"DNET-Term", NULL, NULL, 32, 32, -1, -1,
WBENCHSCREEN
};
void __saveds
term_task()
{
void *chan;
long imask, cmask, conmask;
WIN *win;
char notdone = 1;
short ignorens = 0;
char conc[4];
IOCON iocw;
IOCON iocr;
#ifndef LATTICE
geta4();
#endif
chan = DAccept(LisPort);
if (chan) {
DQueue(chan, 32);
DIoctl(chan, CIO_MODE, 7, 0);
++NHandlers;
Signal(HdPort->mp_SigTask, 1 << HandShakeSig);
if (win = OpenWindow(&Nw)) {
iocw.io_Command = CMD_WRITE;
iocw.io_Data = (APTR)win;
iocw.io_Message.mn_Node.ln_Type = NT_MESSAGE;
iocw.io_Message.mn_ReplyPort = CreatePort(NULL,0);
conmask = 1 << iocw.io_Message.mn_ReplyPort->mp_SigBit;
OpenDevice("console.device", 0, &iocw, 0);
iocr = iocw;
iocr.io_Command = CMD_READ;
imask = 1 << win->UserPort->mp_SigBit;
cmask = 1 << ((PORT *)chan)->mp_SigBit;
iocr.io_Data = (APTR)conc;
iocr.io_Length = sizeof(conc);
SendIO(&iocr);
setsize(&iocw, NULL, win);
while (notdone) {
long mask;
mask = Wait(imask|cmask|conmask);
if (mask & imask) {
IMESS *im;
while (im = (IMESS *)GetMsg(win->UserPort)) {
switch(im->Class) {
case CLOSEWINDOW:
notdone = 0;
break;
case NEWSIZE:
if (ignorens) {
--ignorens;
setsize(&iocw, NULL, win);
} else {
setsize(&iocw, chan, win);
}
break;
}
ReplyMsg((MSG *)im);
}
}
if ((mask & conmask) && CheckIO(&iocr)) {
short i;
char *ptr;
WaitIO(&iocr);
ptr = (char *)iocr.io_Data;
if (iocr.io_Actual > 0) {
for (i = 0; i < iocr.io_Actual; ++i) {
if (ptr[i] == 13)
ptr[i] = 10;
}
DWrite(chan, ptr, i);
iocw.io_Data = (APTR)ptr;
iocw.io_Length = i;
DoIO(&iocw);
}
iocr.io_Data = (APTR)conc;
iocr.io_Length = sizeof(conc);
SendIO(&iocr);
}
if (mask & cmask) {
long n;
char buf[32];
while (n = DNRead(chan, buf, sizeof(buf))) {
if (n == -2) {
short cmd, val;
char aux;
cmd = DGetIoctl(chan, &val, &aux);
if (cmd >= 0)
HandleIoctl(cmd, val, aux, win, &iocw, &ignorens);
continue;
}
if (n < 0) {
notdone = 0;
break;
}
if (buf[0] == 3) /* remote ^C -- done */
notdone = 0;
iocw.io_Data = (APTR)buf;
iocw.io_Length = n;
DoIO(&iocw);
}
}
}
AbortIO(&iocr);
WaitIO(&iocr);
CloseDevice(&iocw);
DeletePort(iocw.io_Message.mn_ReplyPort);
CloseWindow(win);
}
DClose(chan);
{
MSG *msg;
msg = AllocMem(sizeof(MSG), MEMF_PUBLIC);
Forbid();
PutMsg(HdPort, msg);
}
} else {
Forbid();
Signal(HdPort->mp_SigTask, 1 << HandShakeSig);
}
RemTask(NULL);
}
void
HandleIoctl(cmd, val, aux, win, iocw, igns)
short cmd, val;
char aux;
WIN *win;
IOCON *iocw;
short *igns;
{
static short saverows;
short height, width;
short dx, dy;
switch(cmd) {
case CIO_SETROWS:
saverows = val;
break;
case CIO_SETCOLS:
width = val * win->RPort->TxWidth + win->BorderLeft + win->BorderRight;
height= saverows * win->RPort->TxHeight + win->BorderTop + win->BorderBottom;
dx = win->WScreen->Width - (win->LeftEdge + width);
if (dx > 0)
dx = 0;
if (-dx > win->LeftEdge) {
dx = -win->LeftEdge;
width = win->WScreen->Width;
}
dy = win->WScreen->Height - (win->TopEdge + height);
if (dy > 0)
dy = 0;
if (-dy > win->TopEdge) {
dy = -win->TopEdge;
height = win->WScreen->Height;
}
if (dx || dy) {
MoveWindow(win, dx, dy);
}
if (win->Width != width || win->Height != height) {
SizeWindow(win, width - win->Width, height - win->Height);
++*igns;
}
break;
}
}
void
setsize(iocw, chan, win)
IOCON *iocw;
void *chan;
WIN *win;
{
struct ConUnit *cu = (struct ConUnit *)iocw->io_Unit;
static char Term[64];
iocw->io_Data = (APTR)"\033c\033[20h\033[t\033[u";
iocw->io_Length = 13;
DoIO(iocw);
if (chan) {
DIoctl(chan, CIO_SETROWS, (uword)(cu->cu_YMax+1), 0);
DIoctl(chan, CIO_SETCOLS, (uword)(cu->cu_XMax+1), 0);
}
sprintf(Term, "STERM %ld x %ld", cu->cu_YMax+1, cu->cu_XMax+1);
SetWindowTitles(win, Term, (char *)-1);
}